Dockerのマルチアーキテクチャイメージについて調べてみた
Dockerのマルチアーキテクチャイメージについて調べる機会があったのでまとめてみました。
なお今回はデプロイ済みのマルチアーキテクチャイメージをプルして利用する観点でのまとめとなります。
マルチアーキテクチャイメージとは
Dockerイメージは「マルチアーキテクチャ」という仕様をサポートしています。
Docker images can support multiple architectures, which means that a single image may contain variants for different architectures, and sometimes for different operating systems, such as Windows.
When running an image with multi-architecture support, docker will automatically select an image variant which matches your OS and architecture.
Most of the official images on Docker Hub provide a variety of architectures. For example, the busybox image supports amd64, arm32v5, arm32v6, arm32v7, arm64v8, i386, ppc64le, and s390x. When running this image on an x86_64 / amd64 machine, the x86_64 variant will be pulled and run.
上記のDocker, Inc.のドキュメントを抄訳すると、
- 単一のDockerイメージで複数種類のOSやCPUアーキテクチャをサポートさせることができる。
- このイメージを起動させると、Dockerが実行されているホストのアーキテクチャに応じて適切なイメージが自動で選択される。
- Docker Hub上の公式イメージの多くはマルチアーキテクチャをサポートしている。
とのことことです。このマルチアーキテクチャをサポートしたDockerイメージを「マルチアーキテクチャイメージ」と呼びます。
マルチアーキテクチャイメージをプルしてみる
このマルチアーキテクチャイメージをDocker Hubから実際にプルしてみます。今回はAmazon Linux公式リポジトリで試してみます。以下がリポジトリのページです。
このページで[Description]タブ - [Quick reference]の[Supported architectures]の指定(赤丸部分)を見ると、Amazon Linuxの公式イメージはamd64
とarm64v8
に対応したマルチアーキテクチャイメージであることが分かります。
そして[Tags]タブでタグ一覧を見ると、[OS/ARCH]欄でどのタグがどのアーキテクチャに対応しているかを確認することができます。例えばlatest
タグはamd64
とarm64v8
のアーキテクチャに対応したイメージを指していることが分かります。
アーキテクチャの自動選択によるプル
それでは実際にアーキテクチャの自動選択によるプルを試してみます。まず前項でamd64
とarm64v8
に対応していることが確認できたlatest
タグをプルしてみます。
Dockerを実行しているホストマシンのディストリビューションは「Amazon Linux AMI」、CPUアーキテクチャは「x86_64」です。
$ cat /etc/issue Amazon Linux AMI release 2018.03 Kernel \r on an \m $ uname -m x86_64
docker pull <リポジトリ名>:<タグ名>
を実行してlatest
タグをプルしてみます。
$ docker pull amazonlinux:latest latest: Pulling from library/amazonlinux a8d577519c9f: Pull complete Digest: sha256:deadcaae52851831a2f579185eceb9e86c824d67c25334fbd5ef2ee75cf525a9 Status: Downloaded newer image for amazonlinux:latest
プルできました。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE amazonlinux latest cd2d92bc1c0c 21 hours ago 163MB
プルしたイメージの詳細をdocker inspect <リポジトリ名>:<タグ名>
コマンドにより見てみると、"Architecture": "amd64"
とあるのでDockerホストのCPUアーキテクチ「x86_64」に対応するamd64
アーキテクチャのイメージが自動選択されてプルされていることが分かります。
$ docker inspect amazonlinux:latest [ { "Id": "sha256:cd2d92bc1c0c25b0e15c00cfaa44320d84af71ab3fe97280d53a7b769cd96c19", "RepoTags": [ "amazonlinux:latest" ], "RepoDigests": [ "amazonlinux@sha256:deadcaae52851831a2f579185eceb9e86c824d67c25334fbd5ef2ee75cf525a9" ], "Parent": "", "Comment": "", "Created": "2020-04-01T06:46:33.215020639Z", "Container": "78570eeaf7fd35641f7f125766f1c300485dd8cdf5587e03658b003fa3f479d8", "ContainerConfig": {(省略)}, "DockerVersion": "18.09.7", "Author": "", "Config": {(省略)}, "Architecture": "amd64", "Os": "linux", "Size": 162801142, "VirtualSize": 162801142, "GraphDriver": {(省略)}, "RootFS": {(省略)}, "Metadata": {(省略)} } ]
アーキテクチャを指定してプル
イメージのアーキテクチャを指定してプルすることもできます。これには大きく分けて以下の2つの方法があります。
- DIGESTを指定してプル
- アーキテクチャのリポジトリからプル
それぞれ方法でのプルを試してみます。
DIGESTを指定してプルする
Amazon Linuxリポジトリのタグ一覧ページに戻り、それぞれのタグを見るとアーキテクチャ([OS/ARCH])に対応する[DIGEST]が記載されていることが分かります。イメージのプル時にこのDIGESTを指定することにより、そのDIGESTに対応したアーキテクチャ対応のイメージをプルすることができます。amd64
アーキテクチャに対応する49b6d61fd3ef
のページをリンクから開いてみます。
開いたページでamd64
アーキテクチャに対応するDIGESTの全文が確認できます。これをプル時に指定すれば良いです。
DIGESTを指定したイメージのプルはdocker pull <リポジトリ名>:<タグ名>@sha256:<DIGEST>
とコマンドを実行すれば行えます。実際にプルしてみます。
$ docker pull amazonlinux:latest@sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762 sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762: Pulling from library/amazonlinux Digest: sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762 Status: Downloaded newer image for amazonlinux@sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762
プルできました。因みにここでプルされたのはamd64
アーキテクチャ対応のイメージなので、先ほど自動選択によりプルしたものと同じイメージ(cd2d92bc1c0c
)がプルされています。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE amazonlinux latest cd2d92bc1c0c 22 hours ago 163MB
また、DIGESTのページで[OS/ARCH]のコンボボックスから他のアーキテクチャを選択することができます。「linux/arm64/v8」を選択すると、そのアーキテクチャのDIGESTのページに遷移し、こちらのDIGEST全文も確認することができます。
これもプルしてみます。
$ docker pull amazonlinux:latest@sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276 sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276: Pulling from library/amazonlinux 01d0a3bd5b98: Pull complete Digest: sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276 Status: Downloaded newer image for amazonlinux@sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276
IMAGE IDがd5e46d9cf7e0
のイメージが新しくプルされました。ただし、今回プルしたarm64/v8
のイメージは先ほどプルしたのamd64
のイメージとタグ名が重複するので、TAGがnone
となっています。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE amazonlinux latest cd2d92bc1c0c 22 hours ago 163MB amazonlinux <none> d5e46d9cf7e0 23 hours ago 193MB
プルしたイメージの詳細をdocker inspect
コマンドで見てみると"Architecture": "arm64"
とあり、arm64
アーキテクチャのイメージがプルできていることが分かります。
$ docker inspect d5e46d9cf7e0 [ { "Id": "sha256:d5e46d9cf7e04cc6828bbcc8acec3828b5b3aeb2c6b37d78549e26ac882dac0d", "RepoTags": [], "RepoDigests": [ "amazonlinux@sha256:13b345bea4a238e53966ef3f2e0c2586e6c12ecc1dc73155c2538befa4d03276" ], "Parent": "", "Comment": "", "Created": "2020-04-01T05:22:46.624299813Z", "Container": "2428cc8f8dd63efb3b185340588b7c8209d7cb9ef073c3327a8ed89deda3b2f6", "ContainerConfig": {(省略)}, "DockerVersion": "18.09.7", "Author": "", "Config": {(省略)}, "Architecture": "arm64", "Os": "linux", "Size": 193217812, "VirtualSize": 193217812, "GraphDriver": {(省略)}, "RootFS": {(省略)}, "Metadata": {(省略)} } ]
アーキテクチャごとのリポジトリからプルする
前項で、Amazon LinuxリポジトリTOPページの[Description]タブ - [Quick reference]の[Supported architectures]欄にてAmazon Linuxの公式イメージが対応しているアーキテクチャを確認しましたが、この[amd64]と[arm64v8](赤丸部分)が実はそれぞれのアーキテクチャごとのリポジトリのページへのリンクになっています。
[amd64]のリンク先は「amd64/amazonlinux」というamd64アーキテクチャ対応のAmazon Linuxイメージのリポジトリページとなっています。(これはamd64
リポジトリのamazonlinux
というサブリポジトリのページであるとも言えます)
[arm64v8]のリンク先は「arm64v8/amazonlinux」というarm64v8アーキテクチャ対応のAmazon Linuxイメージのリポジトリページとなっています。(これはarm64v8
リポジトリのamazonlinux
というサブリポジトリのページであるとも言えます)
これらのアーキテクチャのリポジトリの[Tag]タブのページでは、そのアーキテクチャに対応しているタグのみの一覧を確認することができます。
そしてこれらのタグはpullコマンドをdocker pull <アーキテクチャ名>/<サブリポジトリ名>:<タグ名>
のように実行すればプルすることができます。この方法であれば、DIGESTを指定せず、かつDockerを実行している環境によらずとも、任意のアーキテクチャに対応したイメージをプルすることができます。
例えばamd64/amazonlinux
リポジトリのlatest
タグのイメージをプルするのであれば以下のように実行します。
$ docker pull amd64/amazonlinux:latest latest: Pulling from amd64/amazonlinux Digest: sha256:49b6d61fd3efc7ec126eddbb9a9c692fe89678d12f69aa96bf834ab10c30c762 Status: Downloaded newer image for amd64/amazonlinux:latest
ちなみに、今しがたプルしたamd64/amazonlinux:latest
のイメージと、先ほどプルしたamazonlinux:latest
のイメージは、プル元のリポジトリは異なりますがIMAGE IDは同じであり、実態は同一イメージであることが分かります。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE amd64/amazonlinux latest cd2d92bc1c0c 28 hours ago 163MB amazonlinux latest cd2d92bc1c0c 28 hours ago 163MB
まとめ
- 単一のDockerイメージ(タグ)で複数種類のOSやCPUアーキテクチャに対応するイメージを「マルチアーキテクチャイメージ」という。
また、ここまで確認したマルチアーキテクチャイメージのプル方法をまとめると以下のようになる。(実行例はamazonlinux
リポジトリからlatest
タグをプルする場合)
- 方法1 アーキテクチャの自動選択によるプル
- コマンド:
docker pull <リポジトリ名>:<タグ名>
- 実行例:
docker pull amazonlinux:latest
- コマンド:
- 方法2 アーキテクチャのDIGESTを指定してプル
- コマンド:
docker pull <リポジトリ名>:<タグ名>@sha256:<アーキテクチャのDIGEST>
- 実行例:
docker pull amazonlinux:latest@sha256:13b345bea…
- コマンド:
- 方法3 アーキテクチャごとのリポジトリからプル
- コマンド:
docker pull <アーキテクチャ名><サブリポジトリ名>:<タグ名>
- 実行例:
docker pull amd64/amazonlinux:latest
- コマンド:
おわりに
以上、マルチアーキテクチャイメージについてプルして利用する観点で調べてまとめてみたという記事でした。
Dockerのマルチアーキテクチャサポートが提供され始めたのはここ2,3年で、AMDアーキテクチャが主に使われるWindowsやLinuxだけでなく、ARMアーキテクチャを主に採用している組み込み機器やIoTデバイスの上でも同じコンテナ環境をシームレスに扱えるようにするための仕様であるようです。
また、機会があれば自分でマルチアーキテクチャイメージをビルドしてリポジトリに登録するということもやってみようと思います。
参考
以上